from apps.common.base.views import *
from gmssl import sm2, func
from project.settings import BASE_DIR
import subprocess
from apps.interface.client.models import Client
from apps.pay.order.dao import OrderDao

class LzPayViewSet(BaseViewSet):
    # 签名类型
    signType = "SM2"
    # 序列号
    signSN = "4919305285"
    # 加密序列号
    encryptSN = "4919305285"
    # 证书密码
    certPwd = "xlmp666888"
    # 平台账户
    merchantNo = "10200074"
    # 账户号
    subMerchantNo = "10200074"
    pubKeyPath = os.path.join(BASE_DIR, 'apps', 'pay', 'lzpay', 'cert', 'sm', '4919305285_SM2_SignCert.cer')
    pfxPath = os.path.join(BASE_DIR, 'apps', 'pay', 'lzpay', 'cert', 'sm', '4919305285_SM2_PrivateKey.sm2')

    # # 签名类型
    # signType = "SM2"
    # # 序列号
    # signSN = "4037020766"
    # # 加密序列号
    # encryptSN = "4037020766"
    # # 证书密码
    # certPwd = "123456"
    # # 平台账户
    # merchantNo = "10200002"
    # # 账户号
    # subMerchantNo = "30100002"
    # pfxPath = os.path.join(BASE_DIR, 'apps', 'pay', 'lzpay', 'cert', 'sm', '4037020766_SM2_PrivateKey.sm2')

    def getSign(self, r_params):
        data = self.signParamSplicing(r_params)
        jar_path = os.path.join(BASE_DIR, 'apps', 'pay', 'lzpay', 'Main.jar')
        args = ['java', '-jar', jar_path, 'sign', self.pfxPath, self.certPwd, data]
        result = subprocess.run(args, capture_output=True, text=True)
        # 输出程序输出
        print('标准输出:', result.stdout.split('\n'))
        result_arr = result.stdout.split('\n')
        sign = ''
        if result.returncode == 0 and len(result_arr) > 1:
            sign = result_arr[len(result_arr)-2]
        return sign
    
    def encrypt_personinfo(self, contactIdNo, contactPhone):
        jar_path = os.path.join(BASE_DIR, 'apps', 'pay', 'lzpay', 'Main.jar')
        args = ['java', '-jar', jar_path, "encrypt", self.pubKeyPath, contactIdNo, contactPhone]
        result = subprocess.run(args, capture_output=True, text=True)
        # 输出程序输出
        print('加密标准输出:', result.stdout.split('\n'))
        result_arr = result.stdout.split('\n')
        personinfo = {}
        if result.returncode == 0 and len(result_arr) > 1:
            personinfo['contactIdNo'] = result_arr[len(result_arr)-4]
            personinfo['contactPhone'] = result_arr[len(result_arr)-3]
            personinfo['digitalEnvelope'] = result_arr[len(result_arr)-2]
        return personinfo
        # return {
        #     "contactIdNo": "q+U2zoCxoubCBQ3TDHDgq7QZc/cDxa+0tbuV0tzRAH8=",
        #     "contactPhone": "KdylEBfLtoYU8WZTy3iGTQ==",
        #     "digitalEnvelope": "MHwCIDop9lYjblDs0toLJE7eJXLiuBk4vWODU1WmGKaQ5eniAiEAjbBaHnAc13hE+RXkOBeSrkctwWeuWGZ0VfGCNtPlM0oEIKjZgOLeJhJDA5uu0d7Ef9bsaN4uwZJ1VTd7BSoAVpVKBBMiCGY9D8v5CaRcuvf30ojln7aY"
        # }

    
    def signParamSplicing(self, paramMap):
        keySet = paramMap.keys()
        keyArray = list(keySet)
        keyArray.sort()
        data = []
        for paramKey in keyArray:
            if paramKey == "sign":
                continue
            value = paramMap.get(paramKey)
            if value is not None and value != "" and value != "null":
                data.append(f"{paramKey}={value}")
        return "&".join(data)

    ''''支付创建'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def createLzPayforMinipro(self, request):
        params = getRequestParams(request)

        if isEmptyStr(params.get('openid')):
            return Response(response_message('openid字段必填'))
        if isEmptyStr(params.get('clientname')):
            return Response(response_message('clientname字段必填'))
        if not params.get("orderId"):
            return Response(response_message('orderId字段必填'))
        try:
            client_model = Client.objects.get(clientname=params.get('clientname'))
            _order = OrderDao().findOneByOrderId(params.get("orderId"))
            if isEmptyStr(_order.scene):
                return Response(response_message('该订单异常，缺少scene参数'))

            # 校验积分
            if _order.realPayIncomes>0:
                if request.user.incomes < _order.realPayIncomes:
                    return Response(response_modalMessage('积分不足，支付失败'))            
            r_params = {
                "signType": self.signType,
                "signSN": self.signSN,
                "encryptSN": self.encryptSN,
                "merchantNo": self.merchantNo,
                "payType": "WX_PAY_JSAPI",
                "bizType": "ONLINE",
                "merOrderNo": params.get("orderId"),
                "currency": "CNY",
                "payerId":  params.get('openid'),
                "notifyUrl": client_model.baseUrl + client_model.notify_url_for_lz,
                "appId": client_model.appid
            }
            # 设置商品名称
            if _order.content:
                content = json.loads(_order.content)
                if content.get('orderItemList') and len(content.get('orderItemList'))>0:
                    r_params["orderDesc"] = content.get('orderItemList')[0].get('itemName')
                else:
                    r_params["orderDesc"] = "鑫珑名品优选商品"
            else:
                r_params["orderDesc"] = "鑫珑名虚拟商品"
            # 设置商品价格
            realPay = 0
            if client_model.realPay > 0:
                realPay = Decimal(client_model.realPay)
            else:
                realPay = _order.realPay
            r_params["tradeAmount"] = int(Decimal(realPay) * 100)
            
            sign = self.getSign(r_params)
            if sign:
                r_params['sign'] = sign
            else:
                return Response(response_error('获取签名失败'))
            url = "https://scan.lzpay.com/api/scanCode/scanCodePay"
            headers = {'content-type': "application/x-www-form-urlencoded;charset=UTF-8"}
            print('r_params', r_params)
            res = requests.post(url, data=r_params, headers=headers)
            res_content = json.loads(res.content)
            print('res_content', res, res_content)
            r_data = {}
        except Exception as e:
            print('乐付支付异常', e)
            return Response(response_message('乐付支付异常'))
        return Response(response_success(r_data))

    '''支付异步回调'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def paybackforMinipro(self, request):
        print('接收到异步回调request', request.body)
        return Response(response_success('成功'))
    

    ''''账户信息查询'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def queryAccountInfo(self, request):
        params = getRequestParams(request)
        r_params =  {
            "signType": self.signType,
            "signSN": self.signSN,
            "encryptSN": self.encryptSN,
            "merchantNo": self.merchantNo
        }
        print('r_params', r_params)
        sign = self.getSign(r_params)
        if sign:
            r_params['sign'] = sign
        else:
            return Response(response_message('获取签名失败'))
        # 输出程序输出
        url = "https://acct.lzpay.com/api/query/queryAccountInfo"
        headers = {'content-type': "application/x-www-form-urlencoded;charset=UTF-8"}
        print('r_params', r_params)
        res = requests.post(url, data=r_params, headers=headers)
        res_content = json.loads(res.content)
        print('res_content', res_content)
        if res_content.get('code') == '00':
            data = json.loads(res_content.get('resultJsonString'))
            return Response(response_success_notScrypt(data))
        else:
            return Response(response_message(res_content.get('message')))
        
    ''''账户注册发送短信'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def registerSmsCode(self, request):
        params = getRequestParams(request, False)
        r_params =  {
            "signType": self.signType,
            "signSN": self.signSN,
            "encryptSN": self.encryptSN,
            "merchantNo": self.merchantNo
        }
        r_params.update({
            "merType": params.get('merType'),
            "contactName": params.get('contactName'),
            "contactEmail": params.get('contactEmail'),
            "contactIdType": params.get('contactIdType'),
            "customerNo": params.get('customerNo')
        })
        # 加密身份证和手机号
        personinfo = self.encrypt_personinfo(params.get('contactIdNo'), params.get('contactPhone'))
        r_params["contactIdNo"] = personinfo.get('contactIdNo')
        r_params["contactPhone"] = personinfo.get('contactPhone')
        r_params["digitalEnvelope"] = personinfo.get('digitalEnvelope')
        sign = self.getSign(r_params)
        if sign:
            r_params['sign'] = sign
        else:
            return Response(response_message('获取签名失败'))
        # 输出程序输出
        url = "https://acct.lzpay.com/api/merchant/registerSmsCode"
        headers = {'content-type': "application/x-www-form-urlencoded;charset=UTF-8"}
        print('r_params', r_params)
        res = requests.post(url, data=r_params, headers=headers)
        res_content = json.loads(res.content)
        print('res_content', res_content)
        if res_content.get('code') == '00':
            data = json.loads(res_content.get('resultJsonString'))
            return Response(response_success_notScrypt(data))
        else:
            return Response(response_message(res_content.get('message')))
    
    ''''账户快捷注册'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def registerSpeedy(self, request):
        params = getRequestParams(request, False)
        r_params = self.baseParams
        r_params.update({
            "merType": params.get('merType'),
            "contactName": params.get('contactName'),
            "contactIdNo": params.get('contactIdNo'),
            "contactPhone": params.get('contactPhone'),
            "contactEmail": params.get('contactEmail'),
            "contactIdType": params.get('contactIdType'),
            "customerNo": params.get('customerNo'),
            "smsCode": params.get('smsCode'),
            "digitalEnvelope": "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAETgH8LDh5XSSNvgJuqelEyPbxzAzirjWmctSojqJoR28vOE94nhDPbncSjGpkl3kvDt7nCeQ0wNElz/GThGCgoA==",
        })
        sign = self.getSign(r_params)
        if sign:
            r_params['sign'] = sign
        else:
            return Response(response_message('获取签名失败'))
        # 输出程序输出
        url = "https://acct.lzpay.com/api/merchant/registerSpeedy"
        headers = {'content-type': "application/x-www-form-urlencoded;charset=UTF-8"}
        # print('r_params', r_params)
        res = requests.post(url, data=r_params, headers=headers)
        res_content = json.loads(res.content)
        if res_content.get('code') == '00':
            data = json.loads(res_content.get('resultJsonString'))
            return Response(response_success_notScrypt(data))
        else:
            return Response(response_message(res_content.get('message')))
        
    
    
